"""
分组模型
支持用户分组管理，用于权限控制和通知协作
"""

from datetime import datetime
from typing import Optional, List, Dict, Any
import uuid
from enum import Enum
from pydantic import BaseModel, Field
from sqlalchemy import Column, String, DateTime, Text, ForeignKey, Enum as SQLEnum, Boolean, JSON
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from src.config.database import Base
# 延迟导入以避免循环依赖
# from src.models.user import User

# 先定义 Pydantic 模型
class GroupType(str, Enum):
    """分组类型"""
    CUSTOM = "custom"
    SYSTEM = "system"


class GroupRole(str, Enum):
    """分组角色"""
    ADMIN = "admin"
    MEMBER = "member"


class ResourceType(str, Enum):
    """资源类型"""
    PROJECT = "project"
    TASK = "task"
    USER = "user"


class PermissionAction(str, Enum):
    """权限操作"""
    READ = "read"
    WRITE = "write"
    DELETE = "delete"


# Pydantic 模型
class GroupCreate(BaseModel):
    """创建分组的请求模型"""
    name: str = Field(..., min_length=1, max_length=100, description="分组名称")
    description: Optional[str] = Field(None, description="分组描述")
    type: GroupType = Field(default=GroupType.CUSTOM, description="分组类型")
    parent_id: Optional[uuid.UUID] = Field(None, description="父分组ID")
    metadata: Optional[Dict[str, Any]] = Field(None, description="分组元数据")


class GroupUpdate(BaseModel):
    """更新分组的请求模型"""
    name: Optional[str] = Field(None, min_length=1, max_length=100, description="分组名称")
    description: Optional[str] = Field(None, description="分组描述")
    type: Optional[GroupType] = Field(None, description="分组类型")
    parent_id: Optional[uuid.UUID] = Field(None, description="父分组ID")
    is_active: Optional[bool] = Field(None, description="是否激活")
    metadata: Optional[Dict[str, Any]] = Field(None, description="分组元数据")


class GroupResponse(BaseModel):
    """分组响应模型"""
    id: uuid.UUID
    name: str
    description: Optional[str]
    type: GroupType
    parent_id: Optional[uuid.UUID]
    is_active: bool
    metadata: Optional[Dict[str, Any]]
    created_at: datetime
    updated_at: datetime
    member_count: Optional[int] = 0  # 成员数量

    class Config:
        from_attributes = True


class UserGroupCreate(BaseModel):
    """添加用户到分组的请求模型"""
    user_id: uuid.UUID = Field(..., description="用户ID")
    role: GroupRole = Field(default=GroupRole.MEMBER, description="用户在分组中的角色")
    metadata: Optional[Dict[str, Any]] = Field(None, description="关联元数据")


class UserGroupResponse(BaseModel):
    """用户-分组关联响应模型"""
    user_id: uuid.UUID
    group_id: uuid.UUID
    role: GroupRole
    joined_at: datetime
    metadata: Optional[Dict[str, Any]]
    user: Optional[Dict[str, Any]]  # 用户信息
    group: Optional[Dict[str, Any]]  # 分组信息

    class Config:
        from_attributes = True
        arbitrary_types_allowed = True


class GroupPermissionCreate(BaseModel):
    """创建分组权限的请求模型"""
    resource_type: ResourceType = Field(..., description="资源类型")
    resource_id: Optional[uuid.UUID] = Field(None, description="资源ID")
    action: PermissionAction = Field(..., description="操作权限")
    conditions: Optional[Dict[str, Any]] = Field(None, description="权限条件")


class GroupPermissionResponse(BaseModel):
    """分组权限响应模型"""
    id: uuid.UUID
    group_id: uuid.UUID
    resource_type: ResourceType
    resource_id: Optional[uuid.UUID]
    action: PermissionAction
    conditions: Optional[Dict[str, Any]]
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True
        arbitrary_types_allowed = True


class GroupFilter(BaseModel):
    """分组筛选条件模型"""
    name: Optional[str] = None
    type: Optional[List[GroupType]] = None
    parent_id: Optional[uuid.UUID] = None
    is_active: Optional[bool] = None
    user_id: Optional[uuid.UUID] = None  # 筛选用户所属的分组


# SQLAlchemy 模型
class Group(Base):
    """分组数据模型"""
    __tablename__ = "groups"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    name = Column(String(100), unique=True, nullable=False, index=True)
    description = Column(String, nullable=True)
    type = Column(SQLEnum(GroupType), default=GroupType.CUSTOM, nullable=False)
    parent_id = Column(UUID(as_uuid=True), ForeignKey('groups.id'), nullable=True, index=True)
    is_active = Column(Boolean, default=True, nullable=False)
    meta = Column(JSON, default=dict, nullable=True)  # 分组元数据
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)

    # 关系
    parent = relationship("Group", remote_side=[id], backref="children")
    user_associations = relationship("UserGroup", back_populates="group", cascade="all, delete-orphan")
    permissions = relationship("GroupPermission", back_populates="group", cascade="all, delete-orphan")


class UserGroup(Base):
    """用户-分组关联模型"""
    __tablename__ = "user_groups"

    user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), primary_key=True, nullable=False)
    group_id = Column(UUID(as_uuid=True), ForeignKey('groups.id'), primary_key=True, nullable=False)
    role = Column(SQLEnum(GroupRole), default=GroupRole.MEMBER, nullable=False)
    joined_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    meta = Column(JSON, default=dict, nullable=True)  # 关联元数据

    # 关系
    user = relationship("User", back_populates="group_associations")
    group = relationship("Group", back_populates="user_associations")


class GroupPermission(Base):
    """分组权限模型"""
    __tablename__ = "group_permissions"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    group_id = Column(UUID(as_uuid=True), ForeignKey('groups.id'), nullable=False, index=True)
    resource_type = Column(SQLEnum(ResourceType), nullable=False)
    resource_id = Column(UUID(as_uuid=True), nullable=True, index=True)
    action = Column(SQLEnum(PermissionAction), nullable=False)
    conditions = Column(JSON, default=dict, nullable=True)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)

    # 关系
    group = relationship("Group", back_populates="permissions")